#pragma once
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QLabel>
#include <QVector>
#include <QSet>
#include <queue>
#include <fstream>
#include <stack>
#include <vector>
#include <thread>
#include <memory>
#include <future>
#include <mutex>
#include <bitset>
#include <unordered_map>
#include "Chess.h"
#include "engine.h"
#include "QPushButton"
#include "QSet"
#include "QComboBox"
#include "mytimer.h"

class Engine;
/*
struct Step;
struct Score_struct;
class Chess;
struct Movechess;
struct Cb_with_num;
*/
namespace Ui {
class MainWindow;
}


class MainWindow : public QMainWindow
{
    int count = 0;
    Q_OBJECT
    //边距以及棋格宽高
    static const int ydis = 25,xdis = 175,chessh = 50,chessw = 24,wh =50;
private:
    const QPixmap * black = new QPixmap(":/imgs\\blackchess.png");
    const QPixmap * white = new QPixmap(":/imgs\\whitechess.png");
    const QPixmap * blackhinder = new QPixmap(":/imgs\\blackhinder.png");
    const QPixmap * whitehinder = new QPixmap(":/imgs\\whitehinder.png");
    const QSizeF * chesssize = new QSizeF(wh,wh);
    QSet<QPushButton *> btn_set;
    QComboBox *box;
    QLabel * fh = new QLabel(this);
    QLabel * lastStep = new QLabel(this);
    QLabel * wait = new QLabel(this);
    std::stack<int> undo_save;
    std::vector<Cb_with_num> cb_save;
    std::vector<Step> step_save;
    Engine *engine;
    class std::thread * cal_t;
    class std::thread * save_t;
    Step cur_s;
    MyTimer * black_timer = new MyTimer("黑方"),* white_timer = new MyTimer("白方");

    //0为白旗，1为黑棋，2为无子,3为越界,4为黑棋箭，5为白旗箭
    bool isfirst = true;
    int win;
    int cur_cb = -1;
    bool during_cal = false;
    QPushButton * setnow = new QPushButton(this);
    //当前选择的先手模式:2为随机，1为玩家先手，0为电脑先手
    QString select = "随机先手";
    bool isfin = true;
    bool save = true;
    //当人机对战时，电脑始终为player2

    enum Mode{
        random = 1,
        human,
        computer_vs_human,
        c_vs_c
    }mode = random;

    //根据坐标获取棋格行列数
    inline void getpos(int x,int y,Chess& pos);
    //返回以x0，y0为当前棋子，在第x列上走斜线时y的值
    inline int rdiagonal(int x,int x0,int y0);
    inline int ldiagonal(int x,int x0,int y0);
    //判断是否为棋子还是障碍
    inline bool isMoveChess(int x,int y,bool player) const;
    //将原来下标为last的棋子移动到cur
    inline void changeMoveChess(const Chess& last,const Chess &cur,bool player);
    //判断移动棋子或放置障碍是否合法
    bool isLegal(const Chess& last,const Chess& cur);
    //先后手决定
    void init_ui();
    void firsthand();
    //初始化棋盘
    void initCb();
    void initTimer();
    void run_time();
    //电脑下子
    void setChess(const Chess& moch,const Chess& setch,const Chess& hinder);
    void wait_cal();
    int winner();
    bool end_game();
    void save_game();

private slots:
    void resetcb();
    void next(){
        run_time();
        while(cur_cb != cb_save.size()-1) {
            cb_save.pop_back();
            step_save.pop_back();
        }
        if (mode == human);
        else if (mode == random && cb_with_num.player == computer) randomSet();
        else if (mode == computer_vs_human && cb_with_num.player == computer) c_vs_hmode();
        else if (mode == c_vs_c) c_vs_cmode();
        cb_save.push_back(cb_with_num);
        cur_cb++;
    }
    //以下为各模式的切换函数
    //随机走子函数
    void randomSet();
    void c_vs_cmode();
    void c_vs_hmode();
    void undo();
    void engine_notyify(Step s);
    void back();
    void go();
signals:
    void complete();
    void computer_first();
    void computer_remote();
    void stop();
public:
    Ui::MainWindow *ui;
    Cb_with_num cb_with_num;
    //当前棋子结构体
    struct Current{;
        Chess chess;
        Chess lastchess;
        int time = 0;
    }current;
    bool computer;
    explicit MainWindow(QWidget *parent = nullptr);
    void mousePressEvent(QMouseEvent *e);
    void paintEvent(QPaintEvent * e);
    ~MainWindow();
    void dispcb(int * chessborad){
        std::ofstream of("C:\\AAAAA\\wu111-1-amazon-chess-dev\\amazon-chess\\ChessBorad\\res.txt");
        if(!of.is_open()) return;
        for (int i = 13;i <= 130;i+=12) {
            for (int j = i;j < i+10;j++ ) {
                of << chessborad[j] << "  ";
            }
            of << std::endl;
        }
    }
};
#endif
